package com.cheer.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cheer.dao.ReferencePlacesDao;
import com.cheer.entity.*;
import com.cheer.enums.OrgTypeEnum;
import com.cheer.enums.ReviewTypeEnum;
import com.cheer.enums.RoleEnum;
import com.cheer.security.UserInfoHolder;
import com.cheer.service.*;
import com.cheer.vo.ReferencePlacesIndexVO;
import com.cheer.vo.ReferencePlacesTswVO;
import com.cheer.vo.ReferencePlacesVO;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


@Service("referencePlacesService")
public class ReferencePlacesServiceImpl extends ServiceImpl<ReferencePlacesDao, ReferencePlacesEntity> implements ReferencePlacesService {

    @Autowired
    private AccountService accountService;

    @Autowired
    private ReferencePlacesDao referencePlacesDao;

    @Autowired
    private ReferenceService referenceService;

    @Autowired
    private UserInfoHolder userInfoHolder;

    @Autowired
    private OrganizationService organizationService;

    @Autowired
    private ReferencePostService referencePostService;


    private final static Integer defaultPlaces = 50;

    @Override
    public void createPlaces() {

        ArrayList<Integer> roles = new ArrayList<Integer>();
        roles.add(RoleEnum.SECOND_ADMIN.getCode());

        List<Organization> organizationList = organizationService.listByOrgRole(roles);
        List<Long> orgIds = organizationList.stream().map(Organization::getId).collect(Collectors.toList());
        String vatage = DateUtil.format(new Date(), "yyyy");
        List<ReferencePlacesEntity> places = referencePlacesDao.selectByVatageAndOrgId(orgIds, vatage);
        List<Long> aliveIds = places.stream().map(ReferencePlacesEntity::getOrgId).collect(Collectors.toList());
        List<ReferencePlacesEntity> saveBatch = new ArrayList<>();

        for (int i = 0; i < organizationList.size(); i++) {

            Organization organization = organizationList.get(i);
            if(aliveIds.contains(organization.getId()) == false){
                // 执行保存操作 默认名额
                ReferencePlacesEntity referencePlacesEntity = new ReferencePlacesEntity();
                referencePlacesEntity.setOrgId(organization.getId());
                referencePlacesEntity.setCount(defaultPlaces);
                referencePlacesEntity.setCross(0);
                if(OrgTypeEnum.AFFAIR.getCode().equals(organization.getOrgType())){
                    referencePlacesEntity.setCross(defaultPlaces/5);
                }
                referencePlacesEntity.setVintage(vatage);
                saveBatch.add(referencePlacesEntity);
            }
        }
        saveBatch(saveBatch);
    }

    @Override
    public ReferencePlacesVO placesInformation() {

        ReferencePlacesVO referencePlacesVO = new ReferencePlacesVO();
        String yyyy = DateUtil.format(new Date(), "yyyy");
        List<ReferencePlacesEntity> referencePlacesEntities = referencePlacesDao.selectByVatageAndOrgId(Lists.newArrayList(userInfoHolder.getAdminOrgId()), yyyy);

        // 没有名额的时候自动去创建名额重新调用
        if(CollectionUtil.isEmpty(referencePlacesEntities)){
            createPlaces();
            referencePlacesEntities = referencePlacesDao.selectByVatageAndOrgId(Lists.newArrayList(userInfoHolder.getAdminOrgId()), yyyy);
        }
        ReferencePlacesEntity referencePlacesEntity = referencePlacesEntities.get(0);
        referencePlacesVO.setCount(referencePlacesEntity.getCount() + referencePlacesEntity.getCross());
        referencePlacesVO.setUsed(referencePlacesEntity.getCrossUsed() + referencePlacesEntity.getUsed());

        return referencePlacesVO;
    }

    @Override
    public ReferencePlacesTswVO tswPlacesInformation(Long orgId, String vintage) {

        ReferencePlacesTswVO referencePlacesTswVO = new ReferencePlacesTswVO();
        Organization organization = organizationService.getById(orgId);
        // 总名额
        Integer count = referencePlacesDao.countByOrgPath(organization.getOrgPath(), vintage);
        // 已使用名额
        Integer reported = referenceService.getReportedCount(organization.getOrgPath(), vintage);
        Integer award = referenceService.getAwardCount(organization.getOrgPath(), vintage);

        if(count == null || count<=award){
            referencePlacesTswVO.setCount(0);
        }else{
            referencePlacesTswVO.setCount(count - award);
        }
        referencePlacesTswVO.setReported(reported);
        referencePlacesTswVO.setAward(award);

        return referencePlacesTswVO;
    }

    @Override
    public ReferencePlacesEntity getByOrgId(Long orgId) {

        return referencePlacesDao.getByOrgId(orgId);
    }

    @Override
    public ReferencePlacesIndexVO tswPlacesIndex(String vintage) {
        ReferencePlacesIndexVO referencePlacesTswVO = new ReferencePlacesIndexVO();
        // 查询所有名额
        Integer reported = referenceService.getReportedCount(null, vintage);
        Integer award = referenceService.getAwardCount(null, vintage);
        referencePlacesTswVO.setReported(reported);
        referencePlacesTswVO.setAward(award);
        return referencePlacesTswVO;
    }

    @Override
    public void reducePlace(Applicant applicant, ReferenceEntity referenceEntity) {

        String yyyy = DateUtil.format(new Date(), "yyyy");
        QueryWrapper<ReferencePostEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(ReferencePostEntity::getApplicantId, applicant.getId())
                        .eq(ReferencePostEntity::getVintage, yyyy);

        List<ReferencePostEntity> list = referencePostService.list(queryWrapper);

        if(CollectionUtil.isNotEmpty(list)){
            referencePostService.removeByIds(list.stream().map(ReferencePostEntity::getId).collect(Collectors.toList()));
        }
        // 查询当前的机构名额
        Integer reviewType = referenceEntity.getReviewType();
        if(ReviewTypeEnum.COMMON.getCode().equals(reviewType)){
            ReferencePlacesEntity referencePlace = getByOrgId(referenceEntity.getOrgId());
            Integer used = referencePlace.getUsed();
            if(used > 0){
                referencePlace.setUsed(used - 1);
            }
            updateById(referencePlace);
        }
        // 联合审批指向最后审批的机构
        if(ReviewTypeEnum.JOIN.getCode().equals(reviewType)){
            ReferencePlacesEntity referencePlace = getByOrgId(referenceEntity.getJoinReviewOrgId());
            Integer crossUsed = referencePlace.getCrossUsed();
            if(crossUsed > 0){
                referencePlace.setCrossUsed(crossUsed - 1);
            }
            updateById(referencePlace);
        }

    }
}